import {
  Observable, of, from,
  tap, mergeMap,
} from 'rxjs'

// 可观察对象
// const o$ = new Observable(subscribe => { // 订阅函数
//   subscribe.next(1) // 订阅者
//   subscribe.next(2)
//   subscribe.next(3)
//   subscribe.complete() // 结束值的生产与发送
// })

// o$.subscribe({ // 观察者
//   next(value) {
//     console.log('next ', value)
//   },
//   complete() {
//     console.log('complete')
//   },
//   error(err) {
//     console.log('error ', err)
//   }
// })

// 可观察对象
// const o1$ = of([ 1, 2, 3 ]) // next  [ 1, 2, 3 ]
// o1$.subscribe({
//   next(value) {
//     console.log('next ', value) // next  [ 1, 2, 3 ]
//   },
//   complete() {
//     console.log('complete')
//   },
//   error(err) {
//     console.log('error ', err)
//   }
// })


// next  1
// next  2
// next  3
// complete
// const o2$ = from([1, 2, 3])
// o2$.subscribe({
//   next(value) {
//     console.log('next ', value)
//   },
//   complete() {
//     console.log('complete')
//   },
//   error(err) {
//     console.log('error ', err)
//   }
// })

// 可观察对象 o3$ Observable<"ok">
const o3$ = from(Promise.resolve('ok'))
// o3$.subscribe({
//   next(value) {
//     console.log('next ', value)
//   },
//   complete() {
//     console.log('complete')
//   },
//   error(err) {
//     console.log('error ', err)
//   }
// })

// 拦截器函数的返回值可能是一个 Promise<可观察对象> 或者是一个可观察对象
async function intercept() {
  return o3$ // Promise<Observable<'ok'>>
}


// Observable<Observable<'ok'>> 可观察对象 生产发送
const o4$ = from(intercept()) //  Observable<Observable<'ok'>>
// o4$.subscribe({
//   next(value) { // Observable<'ok'>
//     console.log('next ', value)
//   },
//   complete() {
//     console.log('complete')
//   },
//   error(err) {
//     console.log('error ', err)
//   }
// })

// o4$ Observable<Observable<'ok'>>
//   project Observable<'ok'>
// ob5$ <'ok'> 新的可观察对象
const ob5$ = o4$.pipe(
  mergeMap(val => val instanceof Observable ? val : of(val)) // project 函数返回的可观察对象称为内部可观察对象
)
// mergeMap 接收一个 project 函数作为参数
//   project 函数会接收上游可观察对象发送的值作为参数
//   project 函数必须返回一个可观察对象
//   project 返回的可观察对象发送的值会传递给下游可观察对象
// mergeMap 会返回一个新的可观察对象
ob5$.subscribe({
  next(value) {
    console.log('ob5$ next ', value)
  },
  complete() {
    console.log('ob5$ complete')
  },
  error(err) {
    console.log('ob5$ error ', err)
  }
})
